package com.gaga.metadata.driver;


import cn.hutool.core.lang.UUID;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.gaga.metadata.common.assertion.Asserts;
import com.gaga.metadata.common.enums.ColumnType;
import com.gaga.metadata.common.enums.DbDDLType;
import com.gaga.metadata.common.utils.StringUtils;
import com.gaga.metadata.entity.base.BaseColumn;
import com.gaga.metadata.entity.database.DataBaseColumn;
import com.gaga.metadata.entity.database.DataBaseSchema;
import com.gaga.metadata.entity.database.DataBaseTable;
import com.gaga.metadata.query.IDBQuery;
import com.gaga.metadata.record.SqlRecordFactory;
import com.gaga.metadata.result.JdbcSelectResult;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * AbstractJdbcDriver
 *
 * @author liujia
 * @since 2021/7/20 14:09
 **/
public abstract class AbstractJdbcDriver extends AbstractDriver {

    private static Logger logger = LoggerFactory.getLogger(AbstractJdbcDriver.class);

    protected static ThreadLocal<Connection> conn = new ThreadLocal<>();

    private DruidDataSource dataSource;

    abstract String getDriverClass();

    abstract String getValidateSql();

    private static final int FETCH_SIZE = 100;

    @Override
    public String test() {
        Asserts.checkNotNull(config, "无效的数据源配置");
        try {
            Class.forName(getDriverClass());
            DriverManager.getConnection(config.getUrl(), config.getUsername(), config.getPassword()).close();
        } catch (Exception e) {
            logger.error("Jdbc链接测试失败！错误信息为：" + e.getMessage(), e);
            return e.getMessage();
        }
        return "ok";
    }

    public DruidDataSource createDataSource() throws SQLException {
        if (null == dataSource) {
            synchronized (this.getClass()) {
                if (null == dataSource) {
                    DruidDataSource ds = new DruidDataSource();
                    createDataSource(ds, config);
                    ds.init();
                    this.dataSource = ds;
                }
            }
        }
        return dataSource;
    }

    @Override
    public Driver setDriverConfig(DriverConfig config) {
        this.config = config;
        try {
            this.dataSource = createDataSource();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        createDataSource(dataSource, config);
        return this;
    }

    protected void createDataSource(DruidDataSource ds, DriverConfig config) {
        ds.setName(config.getName().replaceAll(":", ""));
        ds.setUrl(config.getUrl());
        ds.setDriverClassName(getDriverClass());
        ds.setUsername(config.getUsername());
        ds.setPassword(config.getPassword());
        ds.setValidationQuery(getValidateSql());
        ds.setTestWhileIdle(true);
        ds.setInitialSize(config.getInitialSize() > 0 ? config.getInitialSize() : 20);
        ds.setMaxActive(config.getMaxActiveSize() > 0 ? config.getMaxActiveSize() : 200);
        ds.setMaxWait(3000);
        ds.setRemoveAbandoned(true);
        ds.setRemoveAbandonedTimeout(180);
        ds.setMinIdle(10);
    }

    @Override
    public Driver connect() {
        if (null == conn.get()) {
            try {
                Class.forName(getDriverClass());
                DruidPooledConnection connection = createDataSource().getConnection();
                conn.set(connection);
            } catch (ClassNotFoundException | SQLException e) {
                throw new RuntimeException(e);
            }
        }
        return this;
    }

    @Override
    public boolean isHealth() {
        try {
            if (Asserts.isNotNull(conn.get())) {
                return !conn.get().isClosed();
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void close() {
        try {
            if (Asserts.isNotNull(conn.get())) {
                conn.get().close();
                conn.remove();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void close(PreparedStatement preparedStatement, ResultSet results) {

        try {
            if (Asserts.isNotNull(results)) {
                results.close();
            }
            if (Asserts.isNotNull(preparedStatement)) {
                preparedStatement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<DataBaseSchema> listSchemas() {
        List<DataBaseSchema> schemas = new ArrayList<>();
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        String schemasSql = getDBQuery().schemaAllSql();
        String ip = config.getIp();
        Integer port = config.getPort();
        try {
            preparedStatement = conn.get().prepareStatement(schemasSql);
            results = preparedStatement.executeQuery();
            while (results.next()) {
                String schemaName = results.getString(getDBQuery().schemaName());
                if (Asserts.isNotNullString(schemaName)) {
                    DataBaseSchema schema = new DataBaseSchema(schemaName);
                    schema.setIp(ip);
                    schema.setPort(port);
                    schemas.add(schema);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(preparedStatement, results);
        }
        return schemas;
    }

    @Override
    public List<DataBaseTable> listTables(String schemaName, String tableNameParams) {
        List<DataBaseTable> tableList = new ArrayList<>();
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        IDBQuery dbQuery = getDBQuery();
        String sql = dbQuery.tablesSql(schemaName, tableNameParams);
        try {
            preparedStatement = conn.get().prepareStatement(sql);
            results = preparedStatement.executeQuery();
            ResultSetMetaData metaData = results.getMetaData();
            List<String> columnList = new ArrayList<>();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                columnList.add(metaData.getColumnLabel(i));
            }
            while (results.next()) {
                String tableName = results.getString(dbQuery.tableName());
                if (Asserts.isNotNullString(tableName)) {
                    DataBaseTable tableInfo = new DataBaseTable();
                    tableInfo.setTableName(tableName);
                    tableInfo.setId(UUID.fastUUID().toString());
                    if (columnList.contains(dbQuery.tableComment())) {
                        tableInfo.setComment(results.getString(dbQuery.tableComment()));
                    }
                    tableInfo.setSchema(schemaName);
                    if (columnList.contains(dbQuery.tableType())) {
                        tableInfo.setType(results.getString(dbQuery.tableType()));
                    }
                    if (columnList.contains(dbQuery.catalogName())) {
                        tableInfo.setCatalog(results.getString(dbQuery.catalogName()));
                    }
                    if (columnList.contains(dbQuery.engine())) {
                        tableInfo.setEngine(results.getString(dbQuery.engine()));
                    }
                    if (columnList.contains(dbQuery.options())) {
                        tableInfo.setTableOptions(results.getString(dbQuery.options()));
                    }
                    if (columnList.contains(dbQuery.rows())) {
                        tableInfo.setRows(results.getLong(dbQuery.rows()));
                    }
                    tableList.add(tableInfo);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(preparedStatement, results);
        }
        return tableList;
    }

    @Override
    public List<DataBaseColumn> listColumns(String schemaName, String tableName) {
        List<DataBaseColumn> columns = new ArrayList<>();
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        IDBQuery dbQuery = getDBQuery();
        String tableFieldsSql = dbQuery.columnsSql(schemaName, tableName);
        tableFieldsSql = String.format(tableFieldsSql, tableName);
        try {
            preparedStatement = conn.get().prepareStatement(tableFieldsSql);
            results = preparedStatement.executeQuery();
            ResultSetMetaData metaData = results.getMetaData();
            List<String> columnList = new ArrayList<>();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                columnList.add(metaData.getColumnLabel(i));
            }
            while (results.next()) {
                DataBaseColumn field = new DataBaseColumn();
                String columnName = results.getString(dbQuery.columnName());
                if (columnList.contains(dbQuery.columnKey())) {
                    String key = results.getString(dbQuery.columnKey());
                    field.setKeyFlag(Asserts.isNotNullString(key) && Asserts.isEqualsIgnoreCase(dbQuery.isPK(), key));
                }
                field.setName(columnName);
                String dbType = results.getString(dbQuery.columnType());
                if (columnList.contains(dbQuery.columnType())) {
                    field.setDbType(dbType);
                }

                if (columnList.contains(dbQuery.columnComment()) && Asserts.isNotNull(results.getString(dbQuery.columnComment()))) {
                    String columnComment = results.getString(dbQuery.columnComment()).replaceAll("\"|'", "");
                    field.setComment(columnComment);
                }
                if (columnList.contains(dbQuery.isNullable())) {
                    field.setIsNullable(Asserts.isEqualsIgnoreCase(results.getString(dbQuery.isNullable()), "YES"));
                }
                if (columnList.contains(dbQuery.characterSet())) {
                    field.setCharacterSet(results.getString(dbQuery.characterSet()));
                }
                if (columnList.contains(dbQuery.collation())) {
                    field.setCollation(results.getString(dbQuery.collation()));
                }
//                if (columnList.contains(dbQuery.columnPosition())) {
//                    field.setPosition(results.getInt(dbQuery.columnPosition()));
//                }
                ColumnType columnType = getDataTypeConvert().convert(field);
                if (columnType == ColumnType.DATETIME || columnType == ColumnType.TIME) {
                    if (columnList.contains(dbQuery.dateTimePrecision())) {
                        field.setPrecision(results.getInt(dbQuery.dateTimePrecision()));
                    }
                } else if (columnType == ColumnType.DECIMAL || columnType == ColumnType.INTEGER || columnType == ColumnType.NUMBER) {
                    if (columnList.contains(dbQuery.precision())) {
                        field.setPrecision(results.getInt(dbQuery.precision()));
                    }
                } else {
                    field.setPrecision(results.getInt(dbQuery.length()));
                }
                if (columnList.contains(dbQuery.scale())) {
                    field.setScale(results.getInt(dbQuery.scale()));
                }
                if (columnList.contains(dbQuery.autoIncrement())) {
                    field.setAutoIncrement(Asserts.isEqualsIgnoreCase(results.getString(dbQuery.autoIncrement()), "auto_increment"));
                }
                field.setColumnType(columnType);
                columns.add(field);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(preparedStatement, results);
        }
        return columns;
    }

    @Override
    public boolean createTable(DataBaseTable table) throws Exception {
        //创建表
        String sql = getCreateTableSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public boolean dropThenCreateTable(DataBaseTable table) throws Exception {
        try {
            table.setDdlType(DbDDLType.DROP_TABLE);
            dropTable(table);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        } finally {
            table.setDdlType(DbDDLType.CREATE_TABLE);
            return createTable(table);
        }
    }

    @Override
    public boolean dropTable(DataBaseTable table) throws Exception {
        String sql = getDropTableSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }


    @Override
    public boolean truncateTable(DataBaseTable table) throws Exception {
        String sql = getTruncateTableSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }


    @Override
    public String getCreateTableSql(DataBaseTable table) {
        String createTable = null;
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        String createTableSql = getDBQuery().createTableSql(table.getSchema(), table.getTableName());
        try {
            preparedStatement = conn.get().prepareStatement(createTableSql);
            results = preparedStatement.executeQuery();
            if (results.next()) {
                ResultSetMetaData rsmd = results.getMetaData();
                int columns = rsmd.getColumnCount();
                for (int x = 1; x <= columns; x++) {
                    if (getDBQuery().createTableName().equals(rsmd.getColumnName(x))) {
                        createTable = results.getString(getDBQuery().createTableName());
                        break;
                    }
//                    if (getDBQuery().createViewName().equals(rsmd.getColumnName(x))) {
//                        createTable = results.getString(getDBQuery().createViewName());
//                        break;
//                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(preparedStatement, results);
        }
        return createTable;
    }

    @Override
    public String getDropTableSql(DataBaseTable table) {
        StringBuilder sb = new StringBuilder();
        sb.append("DROP TABLE ");
        if (Asserts.isNotNullString(table.getSchema())) {
            sb.append(table.getSchema() + ".");
        }
        sb.append(table.getTableName());
        return sb.toString();
    }

    @Override
    public String getTruncateTableSql(DataBaseTable table) {
        StringBuilder sb = new StringBuilder();
        sb.append("TRUNCATE TABLE ");
        if (Asserts.isNotNullString(table.getSchema())) {
            sb.append(table.getSchema() + ".");
        }
        sb.append(table.getTableName());
        return sb.toString();
    }

    @Override
    public boolean execute(String sql, DataBaseTable table) throws Exception {
        Asserts.checkNullString(sql, "Sql 语句为空");
        boolean executeResult = true;
        String errorMsg = "";
        try (Statement statement = conn.get().createStatement()) {
            statement.execute(sql);
        } catch (Exception e) {
            errorMsg = e.getMessage();
            executeResult = false;
        } finally {
            SqlRecordFactory.handler(sql, executeResult, errorMsg, table);
        }
        return executeResult;
    }

    @Override
    public int executeUpdate(String sql) throws Exception {
        Asserts.checkNullString(sql, "Sql 语句为空");
        int res = 0;
        try (Statement statement = conn.get().createStatement()) {
            res = statement.executeUpdate(sql);
        }
        return res;
    }

    @Override
    public JdbcSelectResult jdbcSelectByTable(DataBaseTable table) {
        JdbcSelectResult result = new JdbcSelectResult();
        List<LinkedHashMap<String, Object>> datas = new ArrayList<>();
        List<DataBaseColumn> columns = new ArrayList<>();
        List<String> columnNameList = new ArrayList<>();
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        try {

            StringBuffer columsStr = new StringBuffer();
            if (CollectionUtils.isNotEmpty(table.getColumns())) {
                table.getColumns().stream().forEach(column -> columsStr.append(column.getName()).append(","));
            }

            String querySQL = StringUtils.format("select {} from {} {}",
                    CollectionUtils.isNotEmpty(table.getColumns()) ? columsStr.toString().substring(0, columsStr.toString().length() - 1) : "*",
                    table.getTableName(),
                    table.getPage() == null ? "" : getDBQuery().limit(table.getPage().getPageNum(), table.getPage().getPageSize()));

            logger.info("查询的SQL:{}", querySQL);

            preparedStatement = conn.get().prepareStatement(querySQL);
            preparedStatement.setFetchSize(FETCH_SIZE);
            results = preparedStatement.executeQuery();
            if (Asserts.isNull(results)) {
                result.setSuccess(true);
                close(preparedStatement, results);
                return result;
            }
            ResultSetMetaData metaData = results.getMetaData();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                columnNameList.add(metaData.getColumnLabel(i));
                DataBaseColumn column = new DataBaseColumn();
                column.setName(metaData.getColumnLabel(i));
                column.setDbType(metaData.getColumnTypeName(i));
                column.setAutoIncrement(metaData.isAutoIncrement(i));
                column.setIsNullable(metaData.isNullable(i) != 0);
                column.setColumnType(getDataTypeConvert().convert(column));
                columns.add(column);
            }
            result.setColumns(columns);
            while (results.next()) {
                LinkedHashMap<String, Object> data = new LinkedHashMap<>();
                for (int i = 0; i < columns.size(); i++) {
                    data.put(columns.get(i).getName(),
                            getDataTypeConvert().convertValue(results, columns.get(i).getName(), columns.get(i).getColumnType().getCode()));
                }
                datas.add(data);
            }
            result.setSuccess(true);
            result.setTotal(getRecordCount(table));
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            result.setSuccess(false);
        } finally {
            close(preparedStatement, results);
            result.setRowData(datas);
            return result;
        }
    }


    /**
     * 获取表数据总条数
     *
     * @param table
     * @return
     * @throws SQLException
     */
    private Integer getRecordCount(DataBaseTable table) throws SQLException {
        Integer count = 0;

        List<BaseColumn> columns = new ArrayList<>();
        List<LinkedHashMap<String, Object>> datas = new ArrayList<>();

        PreparedStatement preparedStatement = conn.get().prepareStatement("select count(*) as count from " + table.getTableName());
        ResultSet results = preparedStatement.executeQuery();
        if (Asserts.isNull(results)) {
            close(preparedStatement, results);
            return count;
        }
        ResultSetMetaData metaData = results.getMetaData();
        for (int i = 1; i <= metaData.getColumnCount(); i++) {
            DataBaseColumn column = new DataBaseColumn();
            column.setName(metaData.getColumnLabel(i));
            column.setDbType(metaData.getColumnTypeName(i));
            column.setAutoIncrement(metaData.isAutoIncrement(i));
            column.setIsNullable(metaData.isNullable(i) == 0 ? false : true);
            column.setColumnType(getDataTypeConvert().convert(column));
            columns.add(column);
        }

        while (results.next()) {
            LinkedHashMap<String, Object> data = new LinkedHashMap<>();
            for (int i = 0; i < columns.size(); i++) {
                data.put(columns.get(i).getName(),
                        getDataTypeConvert().convertValue(results, columns.get(i).getName(), columns.get(i).getColumnType().getCode()));
            }
            datas.add(data);
        }

        if (CollectionUtils.isNotEmpty(datas)) {
            count = Integer.valueOf((String) datas.get(0).get("count"));
        }

        return count;
    }


    private Integer dealCount(ResultSet results, ResultSetMetaData metaData) throws SQLException {
        Integer count = 0;

        List<BaseColumn> columns = new ArrayList<>();
        List<LinkedHashMap<String, Object>> datas = new ArrayList<>();

        for (int i = 1; i <= metaData.getColumnCount(); i++) {
            DataBaseColumn column = new DataBaseColumn();
            column.setName(metaData.getColumnLabel(i));
            column.setDbType(metaData.getColumnTypeName(i));
            column.setAutoIncrement(metaData.isAutoIncrement(i));
            column.setIsNullable(metaData.isNullable(i) == 0 ? false : true);
            column.setColumnType(getDataTypeConvert().convert(column));
            columns.add(column);
        }

        while (results.next()) {
            LinkedHashMap<String, Object> data = new LinkedHashMap<>();
            for (int i = 0; i < columns.size(); i++) {
                data.put(columns.get(i).getName(),
                        getDataTypeConvert().convertValue(results, columns.get(i).getName(), columns.get(i).getColumnType().getCode()));
            }
            datas.add(data);
        }

        if (CollectionUtils.isNotEmpty(datas)) {
            count = Integer.valueOf((String) datas.get(0).get("count"));
        }

        return count;
    }

    @Override
    public Integer getCount(String sql) {
        Integer count = 0;
        String fortCountSql = "select count(*) from ({}) as countTable";
        String countSql = StringUtils.format(fortCountSql, sql);
        logger.info("count sql is :" + countSql);
        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = conn.get().prepareStatement(countSql);
            ResultSet results = null;
            results = preparedStatement.executeQuery();
            if (Asserts.isNull(results)) {
                close(preparedStatement, results);
                return count;
            }
            ResultSetMetaData metaData = null;

            metaData = results.getMetaData();
            count = dealCount(results, metaData);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    @Override
    public boolean tableHasData(String tableName) {
        return hasColumnData(tableName, null);
    }

    @Override
    public boolean hasColumnData(String tableName, String columnName) {
        Integer count = 0;
        String fortCountSql = "select count(1) as count from {}" + (StringUtils.isNotBlank(columnName) ? " {}" : "");
        String countSql = null;
        if (StringUtils.isNotBlank(columnName)) {
            countSql = StringUtils.format(fortCountSql, tableName, getNotNullSql(columnName));
        } else {
            countSql = StringUtils.format(fortCountSql, tableName);
        }
        logger.info("count sql is :" + countSql);
        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = conn.get().prepareStatement(countSql);
            ResultSet results = null;
            results = preparedStatement.executeQuery();
            if (Asserts.isNull(results)) {
                close(preparedStatement, results);
                return false;
            }
            ResultSetMetaData metaData = null;

            metaData = results.getMetaData();
            count = dealCount(results, metaData);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count > 0;
    }

    @Override
    public String getUninAllSql() {
        return " union all ";
    }

    @Override
    public String getNotNullSql(String columnName) {
        //TODO 这个地方要修改 不是所有的数据库都是下面的语法
        return "where " + columnName + " is not null ";
    }

    @Override
    public JdbcSelectResult query(String sql, Integer limit) {
        if (Asserts.isNull(limit)) {
            limit = 100;
        }

        JdbcSelectResult result = new JdbcSelectResult();
        List<LinkedHashMap<String, Object>> datas = new ArrayList<>();
        List<DataBaseColumn> columns = new ArrayList<>();
        List<String> columnNameList = new ArrayList<>();
        PreparedStatement preparedStatement = null;
        ResultSet results = null;
        int count = 0;
        try {
            preparedStatement = conn.get().prepareStatement(sql);
            preparedStatement.setFetchSize(FETCH_SIZE);
            results = preparedStatement.executeQuery();
            if (Asserts.isNull(results)) {
                result.setSuccess(true);
                close(preparedStatement, results);
                return result;
            }
            ResultSetMetaData metaData = results.getMetaData();
            for (int i = 1; i <= metaData.getColumnCount(); i++) {
                columnNameList.add(metaData.getColumnLabel(i));
                DataBaseColumn column = new DataBaseColumn();
                column.setName(metaData.getColumnLabel(i));
                column.setDbType(metaData.getColumnTypeName(i));
                column.setAutoIncrement(metaData.isAutoIncrement(i));
                column.setIsNullable(metaData.isNullable(i) != 0);
                ColumnType columnType = getDataTypeConvert().convert(column);
                column.setColumnType(columnType);
                column.setIsMeasureColumn(columnType == ColumnType.NUMBER);
                columns.add(column);
            }
            result.setColumns(columns);
            while (results.next()) {
                LinkedHashMap<String, Object> data = new LinkedHashMap<>();
                for (int i = 0; i < columns.size(); i++) {
                    data.put(columns.get(i).getName(),getDataTypeConvert().convertValue(results, columns.get(i).getName(), columns.get(i).getColumnType().getCode()));
                }
                datas.add(data);
                count++;
               /* if (count >= limit) {
                    break;
                }*/
            }
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setError(e.getMessage());
            logger.error("执行的语句为：" + sql);
            result.setSuccess(false);
        } finally {
            close(preparedStatement, results);
            result.setRowData(datas);
            return result;
        }
    }


    @Override
    public boolean batchInsertTableList(String schemaName, String tableName, List<String> columns, List<Map<Integer, String>> dataList) {
        PreparedStatement preparedStatement = null;
        IDBQuery dbQuery = getDBQuery();
        ResultSet results = null;
        String sql = dbQuery.createBatchInsertSql(schemaName, tableName, columns, dataList);
        try {
            this.connect();
            preparedStatement = conn.get().prepareStatement(sql);
            setParams(preparedStatement, dataList);
            logger.info("batch sql is :" + sql);
            preparedStatement.execute();
            return true;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(preparedStatement, results);
            return false;
        }

    }

    private void setParams(PreparedStatement preparedStatement, List<Map<Integer, String>> dataList) {
        int count = 0;
        for (int i = 0; i < dataList.size(); i++) {
            Map<Integer, String> map = dataList.get(i);
            for (Map.Entry<Integer, String> entry : map.entrySet()) {
                count += 1;
                try {
                    preparedStatement.setObject(count, entry.getValue());
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public boolean handlerOperList(List<DataBaseTable> tableList) throws Exception {
        if (CollectionUtils.isEmpty(tableList)) {
            return false;
        }
        List<String> sqlList = new ArrayList<>();
        for (DataBaseTable dataBaseTable : tableList) {
            switch (dataBaseTable.getDdlType()) {
                case ADD_COLUMN:
                    sqlList.add(getAddColunmSql(dataBaseTable).replaceAll("\r\n", " "));
                    break;
                case UPDATE_COLUMN:
                    sqlList.add(getUpdateColunmSql(dataBaseTable).replaceAll("\r\n", " "));
                    break;
                case DEL_COLUMN:
                    sqlList.add(getDelColunmSql(dataBaseTable).replaceAll("\r\n", " "));
                    break;
                case RECREATE_COLUMN:
                    dataBaseTable.setDdlType(DbDDLType.DEL_COLUMN);
                    sqlList.add(getDelColunmSql(dataBaseTable).replaceAll("\r\n", " "));
                    dataBaseTable.setDdlType(DbDDLType.ADD_COLUMN);
                    sqlList.add(getAddColunmSql(dataBaseTable).replaceAll("\r\n", " "));
                    break;
                default:
                    break;
            }
        }
        String reslutSql = String.join(";", sqlList);
        return execute(reslutSql, tableList.get(0));

    }

    @Override
    public boolean addColumn(DataBaseTable table) throws Exception {
        String sql = getAddColunmSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public boolean addIndex(DataBaseTable table) throws Exception {
        String sql = getAddIndexSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }


    @Override
    public String getAddColunmSql(DataBaseTable table) {
        return null;
    }

    @Override
    public String getAddIndexSql(DataBaseTable table) {
        return null;
    }

    @Override
    public boolean updateColumn(DataBaseTable table) throws Exception {
        String sql = getUpdateColunmSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public boolean recreateColumn(DataBaseTable table) throws Exception {
        try {
            table.setDdlType(DbDDLType.DEL_COLUMN);
            delColumn(table);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        } finally {
            table.setDdlType(DbDDLType.ADD_COLUMN);
            return addColumn(table);
        }
    }

    @Override
    public String getUpdateColunmSql(DataBaseTable table) {
        return null;
    }


    @Override
    public boolean delColumn(DataBaseTable table) throws Exception {
        String sql = getDelColunmSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public boolean delIndex(DataBaseTable table) throws Exception {
        String sql = getDelIndexSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }


    @Override
    public String getDelColunmSql(DataBaseTable table) {
        return null;
    }

    @Override
    public String getDelIndexSql(DataBaseTable table) {
        return null;
    }

    @Override
    public boolean updateTable(DataBaseTable table) throws Exception {
        String sql = getUpdateTableSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public String getUpdateTableSql(DataBaseTable table) {
        return null;
    }


    @Override
    public boolean updateIndex(DataBaseTable table) throws Exception {
        String sql = getUpdateIndexSql(table).replaceAll("\r\n", " ");
        logger.info(table.getDdlType().getCode() + "生成的sql====" + sql);
        if (Asserts.isNotNull(sql)) {
            return execute(sql, table);
        } else {
            return false;
        }
    }

    @Override
    public String getUpdateIndexSql(DataBaseTable table) {
        return null;
    }


}
